In [ ]:
import numpy as np
import pandas as pd
from bqplot import (
Axis, ColorAxis, LinearScale, DateScale, DateColorScale, OrdinalScale,
OrdinalColorScale, ColorScale, Scatter, Lines, Figure, Tooltip
)
from ipywidgets import Label
In [ ]:
price_data = pd.DataFrame(np.cumsum(np.random.randn(150, 2).dot([[1.0, -0.8], [-0.8, 1.0]]), axis=0) + 100,
columns=['Security 1', 'Security 2'], index=pd.date_range(start='01-01-2007', periods=150))
size = 100
np.random.seed(0)
x_data = range(size)
y_data = np.cumsum(np.random.randn(size) * 100.0)
ord_keys = np.array(['A', 'B', 'C', 'D', 'E', 'F'])
ordinal_data = np.random.randint(5, size=size)
In [ ]:
symbols = ['Security 1', 'Security 2']
dates_all = price_data.index.values
dates_all_t = dates_all[1:]
sec1_levels = np.array(price_data[symbols[0]].values.flatten())
log_sec1 = np.log(sec1_levels)
sec1_returns = log_sec1[1:] - log_sec1[:-1]
sec2_levels = np.array(price_data[symbols[1]].values.flatten())
In [ ]:
sc_x = DateScale()
sc_y = LinearScale()
scatt = Scatter(x=dates_all, y=sec2_levels, scales={'x': sc_x, 'y': sc_y})
ax_x = Axis(scale=sc_x, label='Date')
ax_y = Axis(scale=sc_y, orientation='vertical', tick_format='0.0f', label='Security 2')
Figure(marks=[scatt], axes=[ax_x, ax_y])
In [ ]:
# Changing the marker as
sc_x = LinearScale()
sc_y = LinearScale()
scatt = Scatter(x=x_data[:10], y=y_data[:10], names=np.arange(10),
scales={'x': sc_x, 'y': sc_y}, colors=['red'], marker='cross')
ax_x = Axis(scale=sc_x)
ax_y = Axis(scale=sc_y, orientation='vertical', tick_format='0.2f')
Figure(marks=[scatt], axes=[ax_x, ax_y], padding_x=0.025)
In [ ]:
scatt.default_opacities = [0.3, 0.5, 1.]
In [ ]:
sc_x = DateScale()
sc_y = LinearScale()
sc_c1 = ColorScale()
scatter = Scatter(x=dates_all, y=sec2_levels, color=sec1_returns,
scales={'x': sc_x, 'y': sc_y, 'color': sc_c1},
stroke='black')
ax_y = Axis(label='Security 2', scale=sc_y,
orientation='vertical', side='left')
ax_x = Axis(label='Date', scale=sc_x, num_ticks=10, label_location='end')
ax_c = ColorAxis(scale=sc_c1, tick_format='0.2%', label='Returns', orientation='vertical', side='right')
m_chart = dict(top=50, bottom=70, left=50, right=100)
Figure(axes=[ax_x, ax_c, ax_y], marks=[scatter], fig_margin=m_chart,
title='Scatter of Security 2 vs Dates')
In [ ]:
## Changing the default color.
scatter.colors = ['blue'] # In this case, the dot with the highest X changes to blue.
In [ ]:
## setting the fill to be empty
scatter.stroke = None
scatter.fill = False
In [ ]:
## Setting the fill back
scatter.stroke = 'black'
scatter.fill = True
In [ ]:
## Changing the color to a different variable
scatter.color = sec2_levels
ax_c.tick_format = '0.0f'
ax_c.label = 'Security 2'
In [ ]:
## Changing the range of the color scale
sc_c1.colors = ['blue', 'green', 'orange']
In [ ]:
sc_x = LinearScale()
sc_y = LinearScale()
sc_c1 = DateColorScale(scheme='Reds')
scatter = Scatter(x=sec2_levels, y=sec1_levels, color=dates_all,
scales={'x': sc_x, 'y': sc_y, 'color': sc_c1}, default_size=128,
stroke='black')
ax_y = Axis(label='Security 1 Level', scale=sc_y, orientation='vertical', side='left')
ax_x = Axis(label='Security 2', scale=sc_x)
ax_c = ColorAxis(scale=sc_c1, label='Date', num_ticks=5)
m_chart = dict(top=50, bottom=80, left=50, right=50)
Figure(axes=[ax_x, ax_c, ax_y], marks=[scatter], fig_margin=m_chart)
In [ ]:
factor = int(np.ceil(len(sec2_levels) * 1.0 / len(ordinal_data)))
ordinal_data = np.tile(ordinal_data, factor)
c_ord = OrdinalColorScale(colors=['DodgerBlue', 'SeaGreen', 'Yellow', 'HotPink', 'OrangeRed'])
sc_x = LinearScale()
sc_y = LinearScale()
scatter2 = Scatter(x=sec2_levels[1:],
y=sec1_returns,
color=ordinal_data,
scales={'x': sc_x, 'y': sc_y, 'color': c_ord},
legend='__no_legend__',
stroke='black')
ax_y = Axis(label='Security 1 Returns', scale=sc_y, orientation='vertical', tick_format='.0%')
ax_x = Axis(label='Security 2', scale=sc_x, label_location='end')
ax_c = ColorAxis(scale=c_ord, label='Class', side='right', orientation='vertical')
m_chart = dict(top=50, bottom=70, left=100, right=100)
Figure(axes=[ax_x, ax_y, ax_c], marks=[scatter2], fig_margin=m_chart)
In [ ]:
ax_c.tick_format = '0.2f'
c_ord.colors = ['blue', 'red', 'green', 'yellow', 'orange']
In [ ]:
sc_x = LinearScale()
sc_y = LinearScale()
sc_y2 = LinearScale()
sc_size = LinearScale()
sc_opacity = LinearScale()
scatter2 = Scatter(x=sec2_levels[1:], y=sec1_levels, size=sec1_returns,
scales={'x': sc_x, 'y': sc_y, 'size': sc_size, 'opacity': sc_opacity},
default_size=128, colors=['orangered'], stroke='black')
ax_y = Axis(label='Security 1', scale=sc_y, orientation='vertical', side='left')
ax_x = Axis(label='Security 2', scale=sc_x)
Figure(axes=[ax_x, ax_y], marks=[scatter2])
In [ ]:
## Changing the opacity of the scatter
scatter2.default_opacities = [0.5, 0.3, 0.1]
In [ ]:
## Resetting the size for the scatter
scatter2.size=None
In [ ]:
## Resetting the opacity and setting the opacity according to the date
scatter2.default_opacities = [1.0]
In [ ]:
scatter2.opacity = dates_all
In [ ]:
sc_x = LinearScale()
sc_y = LinearScale()
sc_e = LinearScale()
scatter = Scatter(scales={'x': sc_x, 'y': sc_y, 'skew': sc_e},
x=sec2_levels[1:], y=sec1_levels,
skew=sec1_returns, stroke="black",
colors=['gold'], default_size=200,
marker='rectangle', default_skew=0)
ax_y = Axis(label='Security 1', scale=sc_y, orientation='vertical', side='left')
ax_x = Axis(label='Security 2', scale=sc_x)
Figure(axes=[ax_x, ax_y], marks=[scatter], animation_duration=1000)
In [ ]:
scatter.skew = None
In [ ]:
scatter.skew = sec1_returns
In [ ]:
sc_x = LinearScale()
sc_y = LinearScale()
sc_e = LinearScale()
sc_c = ColorScale(scheme='Reds')
x1 = np.linspace(-1, 1, 30)
y1 = np.linspace(-1, 1, 30)
x, y = np.meshgrid(x1,y1)
x, y = x.flatten(), y.flatten()
rot = x**2 + y**2
color=x-y
scatter = Scatter(scales={'x': sc_x, 'y': sc_y, 'color': sc_c, 'rotation': sc_e},
x=x, y=y, rotation=rot, color=color,
stroke="black", default_size=200,
marker='arrow', default_skew=0.5,)
Figure(marks=[scatter], animation_duration=1000)
In [ ]:
scatter.rotation = 1.0 / (x ** 2 + y ** 2 + 1)
In [ ]:
## Enabling moving of points in scatter. Try to click and drag any of the points in the scatter and
## notice the line representing the mean of the data update
sc_x = LinearScale()
sc_y = LinearScale()
scat = Scatter(x=x_data[:10], y=y_data[:10], scales={'x': sc_x, 'y': sc_y}, colors=['orange'],
enable_move=True)
lin = Lines(x=[], y=[], scales={'x': sc_x, 'y': sc_y}, line_style='dotted', colors=['orange'])
def update_line(change=None):
with lin.hold_sync():
lin.x = [np.min(scat.x), np.max(scat.x)]
lin.y = [np.mean(scat.y), np.mean(scat.y)]
update_line()
# update line on change of x or y of scatter
scat.observe(update_line, names=['x'])
scat.observe(update_line, names=['y'])
ax_x = Axis(scale=sc_x)
ax_y = Axis(scale=sc_y, tick_format='0.2f', orientation='vertical')
fig = Figure(marks=[scat, lin], axes=[ax_x, ax_y])
fig
In [ ]:
## In this case on drag, the line updates as you move the points.
scat.update_on_move = True
In [ ]:
latex_widget = Label(color='Green', font_size='16px')
def callback_help(name, value):
latex_widget.value = str(value)
latex_widget
In [ ]:
scat.on_drag_start(callback_help)
In [ ]:
scat.on_drag(callback_help)
In [ ]:
scat.on_drag_end(callback_help)
In [ ]:
## Restricting movement to only along the Y-axis
scat.restrict_y = True
In [ ]:
## Enabling adding the points to Scatter. Try clicking anywhere on the scatter to add points
with scat.hold_sync():
scat.enable_move = False
scat.interactions = {'click': 'add'}
In [ ]:
from ipywidgets import ToggleButtons, VBox
interact_control = ToggleButtons(options=['Add', 'Delete', 'Drag XY', 'Drag X', 'Drag Y'],
style={'button_width': '120px'})
def change_interact(change):
interact_parameters = {
'Add': {'interactions': {'click': 'add'},
'enable_move': False},
'Delete': {'interactions': {'click': 'delete'},
'enable_move': False},
'Drag XY': {'interactions': {'click': None},
'enable_move': True,
'restrict_x': False,
'restrict_y': False},
'Drag X': {'interactions': {'click': None},
'enable_move': True,
'restrict_x': True,
'restrict_y': False},
'Drag Y': {'interactions': {'click': None},
'enable_move': True,
'restrict_x': False,
'restrict_y': True}
}
for param, value in interact_parameters[interact_control.value].items():
setattr(scat, param, value)
interact_control.observe(change_interact, names='value')
fig.title = 'Adding/Deleting/Moving points'
VBox([fig, interact_control])
In [ ]:
## Whenever drag is ended, there is a custom event dispatched which can be listened to.
## try dragging a point and see the data associated with the event being printed
def test_func(self, content):
print("received drag end", content)
scat.on_drag_end(test_func)
In [ ]:
x_sc = LinearScale()
y_sc = LinearScale()
x_data = x_data[:50]
y_data = y_data[:50]
def_tt = Tooltip(fields=['x', 'y'], formats=['', '.2f'])
scatter_chart = Scatter(x=x_data, y=y_data, scales= {'x': x_sc, 'y': y_sc}, colors=['dodgerblue'],
tooltip=def_tt, unhovered_style={'opacity': 0.5})
ax_x = Axis(scale=x_sc)
ax_y = Axis(scale=y_sc, orientation='vertical', tick_format='0.2f')
Figure(marks=[scatter_chart], axes=[ax_x, ax_y])
In [ ]:
## removing field names from the tooltip
def_tt.show_labels = False
In [ ]:
## changing the fields displayed in the tooltip
def_tt.fields = ['y']
In [ ]:
def_tt.fields = ['x']